
function Module(uri, deps) {
  this.uri = uri;
  this.dependencies = deps || [];
  this.factory = null;
  this.status = 0;

  //哪些模块依赖我
  this._waitings = {};

  //我依赖的模块还有多少没加载好
  this._remain = 0;
}

var STATUS = Module.STATUS = {
  // 1 - 对应的js文件正在加载
  FETCHING: 1,
  // 2 - js加载完毕，并且已经分析了js文件得到了一些相关信息，存储起来
  SAVED: 2,
  // 3 - 依赖的模块正在加载
  LOADING: 3,
  // 4 - 依赖的模块也都加载好了，处于可执行状态
  LOADED: 4,
  // 5 - 正在执行这个模块
  EXECUTING: 5,
  // 6 - 这个模块执行完成
  EXECUTED: 6
}

//用于加载当前模块所在文件
//加载前状态是STATUS.FETCHING，加载完成后状态是SAVED，加载完成后调用当前模块的load方法
Module.prototype.fetch = function(){

}

/**
 * 用于装载当前模块，装载之前状态为STATUS.LOADING，主要初始化依赖的模块的加载情况
 * 看一下依赖的模块有多少没有达到SAVED的状态，赋值给自己的_remain。另外对还没有加载的模块设置对应的_waitings，增加对自己的引用
 * 挨个检查自己依赖的模块。发现依赖的模块都加载完成，或者没有依赖的模块就直接调用自己的onload
 * 如果发现依赖模块还没有加载的就调用它的fetch让它去加载。
 * 如果已经是加载完了，也就是SAVED状态的，就调用它的load
 */
Module.prototype.load = function(){

}

/**
 * 当前
 */
Module.peototype.onload = function(){

}


/**
 * 辅助函数
 */
cacheMods = {};
Module.get = function(uri, deps){
  return cacheMods[uri] || (cacheMods[uri] = new Module(uri, deps));
}

function id2Url(id) {
  return loaderDir + id + '.js';
}

//解析依赖的模块的实际地址的集合
Module.prototype.resolve = function(){
  var mod = this;
  var ids = mod.dependencies;
  var uris = [];

  for(var i = 0,len = ids.length; i < len; i++) {
    uris[i] = id2Url(ids[i]);
  }

  return uris;
}

function define(factory){
  deps = parseDependencies(factory.toString());
  var meta = {
    deps: deps,
    factory: factory
  };

  //存到一个全局变量
  anonymousMeta = meta;
}

Module.prototype.fetch = function(){
  var mod = this;
  var uri = mod.uri;
  mod.status = STATUS.FETCHING;

  request(uri, onRequest);

  function saveModule(uri, anonymousMeta){
    var mod = Module.get(uri);

    if(mod.status < STATUS.SAVED) {
      mod.id = anonymousMeta.id || uri;
      mod.dependencies = anonymousMeta.deps || [];
      mod.factory = anonymousMeta.factory;
      mod.status = STATUS.SAVED;
    }
  }

  function onRequest(){
    //拿到之前define保存的meta信息
    if(anonymousMeta) {
      saveModule(uri, anonymousMeta);
      anonymousMeta = null;
    }

    mod.load();
  }
}
